package com.meilai.project.service.business.customer.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilai.project.constant.BossUserEnum;
import com.meilai.project.constant.MaintenanceStaffChangeEnum;
import com.meilai.project.controller.mini.vo.customer.MiniCustomerInfoVO;
import com.meilai.project.controller.web.businessFlow.dto.BFCustomerSearchParams;
import com.meilai.project.dto.business.contract.ContractInfoForCustomerDTO;
import com.meilai.project.dto.business.customer.CustomerInfoDTO;
import com.meilai.project.dto.business.customer.CustomerInfoFlowDTO;
import com.meilai.project.entity.business.contract.ContractApply;
import com.meilai.project.entity.business.customer.*;
import com.meilai.project.entity.business.workbench.CustomerEstimateRecord;
import com.meilai.project.entity.business.workbench.Year;
import com.meilai.project.entity.business.workbench.YearWeek;
import com.meilai.project.entity.personnel.org.Department;
import com.meilai.project.entity.system.Dictionary;
import com.meilai.project.entity.system.User;
import com.meilai.project.exception.CommonException;
import com.meilai.project.mapper.business.contract.ContractApplyMapper;
import com.meilai.project.mapper.business.customer.CustomerInfoMapper;
import com.meilai.project.mapper.business.customer.CustomerVisitCommentsMapper;
import com.meilai.project.service.business.customer.*;
import com.meilai.project.service.business.dataLevel.DataQueryBusinessLevelService;
import com.meilai.project.service.business.workbench.CustomerEstimateRecordService;
import com.meilai.project.service.business.workbench.YearService;
import com.meilai.project.service.business.workbench.YearWeekService;
import com.meilai.project.service.personnel.org.DepartmentService;
import com.meilai.project.service.system.DictionaryService;
import com.meilai.project.service.system.UserService;
import com.meilai.project.util.ThreadLocalUserUtil;
import com.meilai.project.vo.business.contract.ContractMediaCountDTO;
import com.meilai.project.vo.business.customer.*;
import com.meilai.project.vo.business.workbench.BaseWeekCustomerVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户信息表 服务实现类
 * </p>
 *
 * @author xhy
 * @since 2022-01-06
 */
@Service
public class CustomerInfoImpl extends ServiceImpl<CustomerInfoMapper, CustomerInfo> implements CustomerInfoService {
    // 万
    private final static BigDecimal ten_thousand = new BigDecimal(10000);
    @Autowired
    private CustomerFollowService customerFollowService;

    @Autowired
    private CustomerFunnelService customerFunnelService;

    @Autowired
    private CustomerSelectionReasonService customerSelectionReasonService;

    @Autowired
    private UserService userService;
    @Autowired
    private CustomerPutStorageService customerPutStorageService;
    @Autowired
    private CustomerContactService customerContactService;
    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private ContractApplyMapper contractApplyMapper;

    @Autowired
    private DictionaryService dictionaryService;

    @Autowired
    private CustomerFollowAdvanceService customerFollowAdvanceService;

    @Autowired
    private CustomerRecommendedResourcesService customerRecommendedResourcesService;

    @Autowired
    private CustomerFollowPhotoService customerFollowPhotoService;

    @Autowired
    private YearService yearService;

    @Autowired
    private YearWeekService yearWeekService;

    @Autowired
    private CustomerEstimateRecordService customerEstimateRecordService;

    @Autowired
    private CustomerMaintainUserRecordService customerMaintainUserRecordService;

    @Autowired
    private DataQueryBusinessLevelService dataQueryBusinessLevelService;

    @Autowired
    private CustomerVisitCommentsMapper customerVisitCommentsMapper;

    @Autowired
    private CustomerInfoFlowService customerInfoFlowService;

    @Autowired
    private CustomerEditFlowService customerEditFlowService;

    @Override
    public Boolean saveOrUpdate(CustomerInfoFlowDTO dto) {
        CustomerInfo info = new CustomerInfo();
        BeanUtils.copyProperties(dto, info);
        info.setId(dto.getCustomer_id());
        info.setCreated_at(null);
        customerFunnelService.remove(Wrappers.<CustomerFunnel>lambdaQuery().eq(CustomerFunnel::getCustomer_id, info.getId()));
        customerSelectionReasonService.remove(Wrappers.<CustomerSelectionReason>lambdaQuery().eq(CustomerSelectionReason::getCustomer_id, info.getId()));
        info.setStatus(1);
        boolean flag = this.saveOrUpdate(info);
        customerFollowService.saveBatch(dto.getFollows(), info.getId());
        customerFunnelService.saveBatch(dto.getFunnels().stream().map(item -> {
            CustomerFunnel customerFunnel = new CustomerFunnel();
            customerFunnel.setFunnel_type_id(item);
            customerFunnel.setCustomer_id(info.getId());
            return customerFunnel;
        }).collect(Collectors.toList()));
        customerSelectionReasonService.saveBatch(dto.getSelection_reasons().stream().map(item -> {
            CustomerSelectionReason selectionReason = new CustomerSelectionReason();
            selectionReason.setCustomer_id(info.getId());
            selectionReason.setSelection_reason_id(item);
            return selectionReason;
        }).collect(Collectors.toList()));
        dto.setCustomer_id(info.getId());
        return flag;
    }

    @Override
    public Page<CustomerInfoVO> page(Integer current_page, Integer page_size, String name, Long industry_id, Boolean is_my_customer_page, Integer type, Long maintenance_staff_id) {
        Page<CustomerInfoVO> page = new Page<CustomerInfoVO>(current_page, page_size);
        Long userId = ThreadLocalUserUtil.get().getId();
        List<Long> userIds = new ArrayList<>();
        userIds.add(userId);
        if (!is_my_customer_page) {
            List<Long> dept = userService.getUserResponsibleDeptIdByBusinessHead(userId);
            if (dept.size() != 0) {
                for (int i = 0; i < dept.size(); i++) {
                    List<User> users = userService.getUserByDeptId(dept.get(i));
                    if (users != null && users.size() > 0) users.forEach(item -> userIds.add(item.getId()));
                }
            }
        }
        // 获取boss_ids
        List<Long> boss_ids = new ArrayList<>(Arrays.asList(BossUserEnum.values())).stream().map(BossUserEnum::getId).collect(Collectors.toList());
        page.setRecords(baseMapper.page(page, name, industry_id, userIds, type, boss_ids, maintenance_staff_id));
        return page;
    }

    @Override
    public Page<CustomerInfoVO> pageForBF(BFCustomerSearchParams params) {
        Page<CustomerInfoVO> page = new Page<CustomerInfoVO>(params.getPage(), params.getPage_size());
        List<Long> userIds = new ArrayList<>();
        if (params.getIsCurrentUserMaintain()) {
            userIds.add(ThreadLocalUserUtil.get().getId());
        }
        page.setRecords(baseMapper.page(page, params.getName(), null, userIds, null, null, null));
        return page;
    }

    @Override
    public List<CustomerInfo> listAll() {
        Long userId = ThreadLocalUserUtil.get().getId();
        List<CustomerInfo> collect = baseMapper.listAll(userId).stream().sorted(Comparator.comparing(CustomerInfo::getName)).collect(Collectors.toList());
        for (CustomerInfo customerInfo : collect) {
            customerInfo.setIs_company_customer(BossUserEnum.getEnumById(customerInfo.getPerson_in_charge_id()) != null);
        }
        return collect;
    }

    @Override
    public List<CustomerInfo> companyListAll() {
        List<CustomerInfo> collect = baseMapper.listAll(null).stream().sorted(Comparator.comparing(CustomerInfo::getName)).collect(Collectors.toList());
        for (CustomerInfo customerInfo : collect) {
            customerInfo.setIs_company_customer(BossUserEnum.getEnumById(customerInfo.getPerson_in_charge_id()) != null);
        }
        return collect;
    }

    @Override
    public List<ContractInfoForCustomerDTO> getContractInfosByCustomerId(Long customerId) {
        List<ContractInfoForCustomerDTO> result = new ArrayList<>();

        List<ContractApply> contractList = contractApplyMapper.selectList(Wrappers.<ContractApply>lambdaQuery()
                .isNull(ContractApply::getDeleted_at)
                .eq(ContractApply::getFlow_status, 4)
                .eq(ContractApply::getMode, 0)
                .eq(ContractApply::getCustomer_id, customerId));

        if(CollectionUtils.isNotEmpty(contractList)){
            Map<Long, ContractApply> cMap = contractList.stream().collect(Collectors.toMap(ContractApply::getId, Function.identity()));
            // 自有资源和代理资源
            List<ContractMediaCountDTO> mediaCounts = contractApplyMapper.getMediaTypeCount(new ArrayList<>(cMap.keySet()));
            Map<Long, List<ContractMediaCountDTO>> mediaCountMap = new HashMap<>();
            Map<Long, List<ContractMediaCountDTO>> proxyMediaCountMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(mediaCounts)) {
                mediaCountMap = mediaCounts.stream().filter(item -> item.getType() == 1).collect(Collectors.groupingBy(ContractMediaCountDTO::getId));
                proxyMediaCountMap = mediaCounts.stream().filter(item -> item.getType() == 2).collect(Collectors.groupingBy(ContractMediaCountDTO::getId));
            }

            for (Map.Entry<Long, ContractApply> entry : cMap.entrySet()) {
                ContractApply cur = entry.getValue();
                result.add(new ContractInfoForCustomerDTO(
                        cur.getSign_date(),
                        cur.getDiscounted_price(),
                        cur.getDiscounted_price_big(),
                        mediaCountMap.getOrDefault(cur.getId(), new ArrayList<>()),
                        proxyMediaCountMap.getOrDefault(cur.getId(), new ArrayList<>())
                ));
            }
            result = result.stream().sorted(Comparator.comparing(ContractInfoForCustomerDTO::getMonth).reversed()).collect(Collectors.toList());
        }

        return result;
    }

    @Override
    public CustomerInfoDTO getOneDtoById(Long id) {
        CustomerInfoDTO dto = baseMapper.getOneDtoById(id);
        Long user_id = ThreadLocalUserUtil.get().getId();
        int level = dataQueryBusinessLevelService.getUserMaxLevel("customer_contact", user_id);
        if (dto != null && CollectionUtils.isNotEmpty(dto.getFollows())) {
            List<Long> collect = dto.getFollows().stream().map(CustomerFollow::getId).collect(Collectors.toList());
            Map<Long, List<CustomerFollowPhoto>> map = customerFollowPhotoService.list(Wrappers.<CustomerFollowPhoto>lambdaQuery().in(CustomerFollowPhoto::getFollow_id, collect)).stream().collect(Collectors.groupingBy(CustomerFollowPhoto::getFollow_id));
            dto.getFollows().forEach(item -> {
                if (map.containsKey(item.getId())) {
                    item.setUrl_list(map.get(item.getId()).stream().map(CustomerFollowPhoto::getUrl).collect(Collectors.toList()));
                } else {
                    item.setUrl_list(new ArrayList<>());
                }
            });
        }
        List<CustomerContact> list = customerContactService.list(Wrappers.<CustomerContact>lambdaQuery().eq(CustomerContact::getCustomer_id, dto.getId()));
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(customerContact -> {
                if (level != -1 && level <= customerContact.getLevel_num()) {
                    customerContact.setCan_look(true);
                }
            });
        }
        dto.setContactsList(list);
        dto.setPutStorageList(customerPutStorageService.list(Wrappers.<CustomerPutStorage>lambdaQuery().eq(CustomerPutStorage::getCustomer_id, dto.getId())));
        dto.setContractList(getContractInfosByCustomerId(id));
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean edit(Long id, Long maintenance_staff_id) {
        CustomerInfo customerInfo = this.getById(id);
        if (customerInfo == null) {
            throw new CommonException("客户数据不存在");
        }
        CustomerMaintainUserRecord customerMaintainUserRecord = new CustomerMaintainUserRecord();
        customerMaintainUserRecord.setCustomer_id(id);
        customerMaintainUserRecord.setOld_maintain_user_id(customerInfo.getMaintenance_staff_id());
        customerMaintainUserRecord.setNew_maintain_user_id(maintenance_staff_id);
        customerMaintainUserRecord.setType(MaintenanceStaffChangeEnum.BU_MENG_ZHI_PAI.getId());
        customerMaintainUserRecord.setUpdate_time(LocalDateTime.now());
        return this.update(Wrappers.<CustomerInfo>lambdaUpdate().set(CustomerInfo::getMaintenance_staff_id, maintenance_staff_id).eq(CustomerInfo::getId, id)) && customerMaintainUserRecordService.save(customerMaintainUserRecord);
    }

    @Override
    public Page<CustomerInfoVO> allPage(Integer current_page, Integer page_size, String name, Long industry_id, Boolean follow_up, Long deptId) {
        Page<CustomerInfoVO> page = new Page<>(current_page, page_size);
        List<Department> list = departmentService.list();
        Map<Long, String> deptNameMap = new HashMap<>();
        list.forEach(item -> {
            deptNameMap.put(item.getId(), departmentService.getDeptCompleteNameById(item.getId()));
        });
        List<CustomerInfoVO> records = baseMapper.allPage(page, name, industry_id, follow_up, deptId);
        for (CustomerInfoVO record : records) {
            if (CollectionUtils.isNotEmpty(record.getDeptIds())) {
                for (Long id : record.getDeptIds()) {
                    if (deptNameMap.get(id) != null) {
                        if (record.getDept() == null || record.getDept().equals("")) {
                            record.setDept(deptNameMap.get(id));
                        } else {
                            record.setDept(record.getDept() + "、" + deptNameMap.get(id));
                        }
                    }
                }
            }
        }
        page.setRecords(records);
        return page;
    }

    public List<BaseWeekCustomerVO> queryCustomerInfoByDate(Long userId, Integer type, LocalDate begin_date, LocalDate end_date) {
        List<Long> boss_ids = new ArrayList<>(Arrays.asList(BossUserEnum.values())).stream().map(BossUserEnum::getId).collect(Collectors.toList());
        return baseMapper.queryCustomerInfoByDate(userId, type, begin_date, end_date, boss_ids);
    }

    @Override
    public List<CustomerAdvanceVO> advanceList() {
        Long user_id = ThreadLocalUserUtil.get().getId();
        List<CustomerAdvanceVO> list = baseMapper.queryAdvanceList(user_id);
        List<Long> customer_ids = list.stream().map(CustomerAdvanceVO::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(customer_ids)) {
            customer_ids.add(-1L);
        }
        // 查询有效的合同列表
        Map<Long, List<ContractApply>> contract_map = contractApplyMapper.queryEffectiveContractList(null, null, customer_ids).stream().collect(Collectors.groupingBy(ContractApply::getCustomer_id));
        // 查询字典数据
        Map<Long, List<Dictionary>> action_dict_map = dictionaryService.listByCode("khxg-tjdz").stream().collect(Collectors.groupingBy(Dictionary::getId));
        Map<Long, List<Dictionary>> resource_dict_map = dictionaryService.listByCode("khxg-tjzy").stream().collect(Collectors.groupingBy(Dictionary::getId));
        // 查询最新的根据记录
        List<CustomerFollow> customerFollows = customerFollowService.queryLatestRecord(customer_ids);
        Map<Long, List<CustomerFollow>> follow_map = customerFollows.stream().collect(Collectors.groupingBy(CustomerFollow::getCustomer_id));
        List<Long> follow_ids = customerFollows.stream().map(CustomerFollow::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(follow_ids)) {
            follow_ids.add(-1L);
        }
        // 查询推进动作数据
        Map<Long, List<CustomerFollowAdvance>> advance_map = customerFollowAdvanceService.list(Wrappers.<CustomerFollowAdvance>lambdaQuery().in(CustomerFollowAdvance::getCustomer_follow_id, follow_ids)).stream().collect(Collectors.groupingBy(CustomerFollowAdvance::getCustomer_follow_id));
        // 查询推荐资源数据
        Map<Long, List<CustomerRecommendedResources>> resource_map = customerRecommendedResourcesService.list(Wrappers.<CustomerRecommendedResources>lambdaQuery().in(CustomerRecommendedResources::getCustomer_follow_id, follow_ids)).stream().collect(Collectors.groupingBy(CustomerRecommendedResources::getCustomer_follow_id));
        // 获取boss_ids
        List<Long> boss_ids = new ArrayList<>(Arrays.asList(BossUserEnum.values())).stream().map(BossUserEnum::getId).collect(Collectors.toList());
        Map<Long, CustomerVisitComments> customerVisitCommentsMap = customerVisitCommentsMapper.queryLastCustomerVisitComments().stream().collect(Collectors.toMap(CustomerVisitComments::getCustomer_id, item -> item));
        list.forEach(item -> {
            // 将预估额度换算为万元
            if (item.getNewest_contract_amount() != null) {
                item.setNewest_contract_amount(item.getNewest_contract_amount().divide(new BigDecimal("10000"), 6, RoundingMode.HALF_UP));
            }
            // 设置是否是公司或个人客户
            if (boss_ids.contains(item.getPerson_in_charge_id())) {
                item.setType(1);
            } else {
                item.setType(2);
            }
            // 设置符合条件的合同
            if (contract_map.containsKey(item.getId())) {
                List<ContractApply> contractApplies = contract_map.get(item.getId()).stream().filter(contract -> contract.getFlow_applyer_id().equals(user_id)).collect(Collectors.toList());
                BigDecimal pay_cash_amount_count = new BigDecimal(0);
                BigDecimal displace_amount_count = new BigDecimal(0);
                if (item.getNewest_transaction_begin_date() != null && item.getNewest_transaction_end_date() != null && CollUtil.isNotEmpty(contractApplies)) {
                    List<ContractApply> collect = contractApplies.stream().filter(contract -> (contract.getSign_date().isBefore(item.getNewest_transaction_end_date()) || contract.getSign_date().equals(item.getNewest_transaction_end_date())) && (contract.getSign_date().isAfter(item.getNewest_transaction_begin_date()) || contract.getSign_date().equals(item.getNewest_transaction_begin_date()))).collect(Collectors.toList());
                    for (ContractApply contractApply : collect) {
                        pay_cash_amount_count = pay_cash_amount_count.add(contractApply.getPay_cash_amount());
                        displace_amount_count = displace_amount_count.add(contractApply.getDisplace_amount());
                    }
                }
                item.setNewest_contract_pay_cash_amount(pay_cash_amount_count);
                item.setNewest_contract_displace_amount(displace_amount_count);
            }
            // 处理拜访记录
            if (follow_map.containsKey(item.getId())) {
                CustomerFollowVO followVO = new CustomerFollowVO();
                CustomerFollow customerFollow = follow_map.get(item.getId()).get(0);
                BeanUtils.copyProperties(customerFollow, followVO);
                if (advance_map.containsKey(customerFollow.getId())) {
                    List<CustomerFollowAdvance> customerFollowAdvances = advance_map.get(customerFollow.getId());
                    List<String> stringList = new ArrayList<>();
                    for (CustomerFollowAdvance customerFollowAdvance : customerFollowAdvances) {
                        if (action_dict_map.containsKey(customerFollowAdvance.getAdvance_id())) {
                            List<Dictionary> dict = action_dict_map.get(customerFollowAdvance.getAdvance_id());
                            stringList.add(dict.get(0).getName());
                        }
                    }
                    followVO.setPropelling_action_name(stringList);
                }
                if (resource_map.containsKey(customerFollow.getId())) {
                    List<CustomerRecommendedResources> customerRecommendedResources = resource_map.get(customerFollow.getId());
                    List<String> stringList = new ArrayList<>();
                    for (CustomerRecommendedResources resource : customerRecommendedResources) {
                        if (resource_dict_map.containsKey(resource.getResources_id())) {
                            List<Dictionary> dict = resource_dict_map.get(resource.getResources_id());
                            stringList.add(dict.get(0).getName());
                        }
                    }
                    followVO.setRecommend_resource_name(stringList);
                }
                item.setCustomerFollowVO(followVO);
            }
            if (item.getVisit_count() == null) {
                item.setVisit_count(0);
            }
            // todo 增加批注信息
            item.setLastCustomerVisitComments(customerVisitCommentsMap.get(item.getId()));
        });
        return list;
    }

    @Override
    public Page<CustomerFollowVO> visitRecordList(Integer current_page, Integer page_size, Long customer_id, String contact_name, LocalDate begin_date, LocalDate end_date) {
        Page<CustomerFollowVO> page = new Page<>();
        Page<CustomerFollow> tmpPage = customerFollowService.page(new Page<>(), Wrappers.<CustomerFollow>lambdaQuery().eq(customer_id != null, CustomerFollow::getCustomer_id, customer_id).like(StringUtils.isNotEmpty(contact_name), CustomerFollow::getOpposite_person, contact_name).ge(begin_date != null, CustomerFollow::getFollow_time, begin_date).le(end_date != null, CustomerFollow::getFollow_time, end_date).orderByDesc(CustomerFollow::getFollow_time));
        List<CustomerFollow> records = tmpPage.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            List<Long> ids = records.stream().map(CustomerFollow::getId).collect(Collectors.toList());
            Map<Long, List<CustomerFollowAdvance>> advance_map = customerFollowAdvanceService.list(Wrappers.<CustomerFollowAdvance>lambdaQuery().in(CustomerFollowAdvance::getCustomer_follow_id, ids)).stream().collect(Collectors.groupingBy(CustomerFollowAdvance::getCustomer_follow_id));
            Map<Long, List<CustomerRecommendedResources>> resource_map = customerRecommendedResourcesService.list(Wrappers.<CustomerRecommendedResources>lambdaQuery().in(CustomerRecommendedResources::getCustomer_follow_id, ids)).stream().collect(Collectors.groupingBy(CustomerRecommendedResources::getCustomer_follow_id));
            // 查询字典数据
            Map<Long, List<Dictionary>> action_dict_map = dictionaryService.listByCode("khxg-tjdz").stream().collect(Collectors.groupingBy(Dictionary::getId));
            Map<Long, List<Dictionary>> resource_dict_map = dictionaryService.listByCode("khxg-tjzy").stream().collect(Collectors.groupingBy(Dictionary::getId));
            Map<Long, List<CustomerFollowPhoto>> map = customerFollowPhotoService.list(Wrappers.<CustomerFollowPhoto>lambdaQuery().in(CustomerFollowPhoto::getFollow_id, ids)).stream().collect(Collectors.groupingBy(CustomerFollowPhoto::getFollow_id));
            List<CustomerFollowVO> collect = records.stream().map(item -> {
                CustomerFollowVO vo = new CustomerFollowVO();
                BeanUtils.copyProperties(item, vo);
                if (advance_map.containsKey(item.getId())) {
                    List<CustomerFollowAdvance> customerFollowAdvances = advance_map.get(item.getId());
                    List<String> stringList = new ArrayList<>();
                    for (CustomerFollowAdvance customerFollowAdvance : customerFollowAdvances) {
                        if (action_dict_map.containsKey(customerFollowAdvance.getAdvance_id())) {
                            List<Dictionary> dict = action_dict_map.get(customerFollowAdvance.getAdvance_id());
                            stringList.add(dict.get(0).getName());
                        }
                    }
                    vo.setPropelling_action_name(stringList);
                }
                if (resource_map.containsKey(item.getId())) {
                    List<CustomerRecommendedResources> customerRecommendedResources = resource_map.get(item.getId());
                    List<String> stringList = new ArrayList<>();
                    for (CustomerRecommendedResources resource : customerRecommendedResources) {
                        if (resource_dict_map.containsKey(resource.getResources_id())) {
                            List<Dictionary> dict = resource_dict_map.get(resource.getResources_id());
                            stringList.add(dict.get(0).getName());
                        }
                    }
                    vo.setRecommend_resource_name(stringList);
                }
                if (map.containsKey(item.getId())) {
                    vo.setImg_list(map.get(item.getId()).stream().map(CustomerFollowPhoto::getUrl).collect(Collectors.toList()));
                } else {
                    vo.setImg_list(new ArrayList<>());
                }
                return vo;
            }).collect(Collectors.toList());
            page.setRecords(collect);
        } else {
            page.setRecords(new ArrayList<>());
        }
        page.setTotal(tmpPage.getTotal());
        page.setCurrent(tmpPage.getCurrent());
        page.setSize(tmpPage.getSize());
        return page;
    }

    @Override
    public List<CompanyCustomerAdvanceVO> companyAdvanceList(Integer year, Integer month, List<Long> ids) {
        Year one = yearService.getOne(Wrappers.<Year>lambdaQuery().eq(Year::getYear, year).eq(Year::getType, month <= 6 ? 1 : 2));
        if (one == null) {
            one = new Year();
            one.setYear("-1");
            one.setType(-1);
        }
        List<YearWeek> yearWeekList = yearWeekService.list(Wrappers.<YearWeek>lambdaQuery().eq(YearWeek::getYear_id, one.getId()).eq(YearWeek::getMonth, month));
        List<Long> week_ids = yearWeekList.stream().map(YearWeek::getId).collect(Collectors.toList());
        Map<Long, YearWeek> week_map = yearWeekList.stream().collect(Collectors.toMap(YearWeek::getId, Function.identity()));
        if (CollectionUtils.isEmpty(week_ids)) {
            week_ids.add(-1L);
        }
        List<CompanyCustomerAdvanceVO> companyAdvanceList = baseMapper.queryCompanyAdvanceList(ids);
        LocalDate begin_date = LocalDate.of(year, month, 1);
        LocalDate end_date = begin_date.with(TemporalAdjusters.lastDayOfMonth());
        List<Long> customer_ids = companyAdvanceList.stream().map(CompanyCustomerAdvanceVO::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(customer_ids)) {
            customer_ids.add(-1L);
        }
        // 查询时间段内的客户预估时间数据
        Map<Long, List<CustomerEstimateRecord>> customer_estimate_record_map = customerEstimateRecordService.queryListByCustomerIdsAndWeekIds(customer_ids, week_ids).stream().collect(Collectors.groupingBy(CustomerEstimateRecord::getCustomer_id));
        // 查询有效的合同列表
        Map<Long, List<ContractApply>> contract_map = contractApplyMapper.queryEffectiveContractList(begin_date, end_date, customer_ids).stream().collect(Collectors.groupingBy(ContractApply::getCustomer_id));
        // 查询字典数据
        Map<Long, List<Dictionary>> action_dict_map = dictionaryService.listByCode("khxg-tjdz").stream().collect(Collectors.groupingBy(Dictionary::getId));
        Map<Long, List<Dictionary>> resource_dict_map = dictionaryService.listByCode("khxg-tjzy").stream().collect(Collectors.groupingBy(Dictionary::getId));
        // 查询最新的根据记录
        List<CustomerFollow> customerFollows = customerFollowService.queryLatestRecord(customer_ids);
        Map<Long, List<CustomerFollow>> follow_map = customerFollows.stream().collect(Collectors.groupingBy(CustomerFollow::getCustomer_id));
        List<Long> follow_ids = customerFollows.stream().map(CustomerFollow::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(follow_ids)) {
            follow_ids.add(-1L);
        }
        // 查询推进动作数据
        Map<Long, List<CustomerFollowAdvance>> advance_map = customerFollowAdvanceService.list(Wrappers.<CustomerFollowAdvance>lambdaQuery().in(CustomerFollowAdvance::getCustomer_follow_id, follow_ids)).stream().collect(Collectors.groupingBy(CustomerFollowAdvance::getCustomer_follow_id));
        // 查询推荐资源数据
        Map<Long, List<CustomerRecommendedResources>> resource_map = customerRecommendedResourcesService.list(Wrappers.<CustomerRecommendedResources>lambdaQuery().in(CustomerRecommendedResources::getCustomer_follow_id, follow_ids)).stream().collect(Collectors.groupingBy(CustomerRecommendedResources::getCustomer_follow_id));
        // 获取boss_ids
        List<Long> boss_ids = new ArrayList<>(Arrays.asList(BossUserEnum.values())).stream().map(BossUserEnum::getId).collect(Collectors.toList());
        Map<Long, CustomerVisitComments> customerVisitCommentsMap = customerVisitCommentsMapper.queryLastCustomerVisitComments().stream().collect(Collectors.toMap(CustomerVisitComments::getCustomer_id, item -> item));
        final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 查询本月的预估记录
        companyAdvanceList.forEach(item -> {
            // 设置是否是公司或个人客户
            if (boss_ids.contains(item.getPerson_in_charge_id())) {
                item.setType(1);
            } else {
                item.setType(2);
            }
            List<CustomerEstimateRecordVO> list = new ArrayList<>();
            //todo 如果有签约记录根据签约记录显示 如果有合同则根据合同创建
            week_map.forEach((week_id, week) -> {
                List<CustomerEstimateRecord> customerEstimateRecords = customer_estimate_record_map.getOrDefault(item.getId(), new ArrayList<>()).stream().filter(record -> record.getWeek_id().equals(week_id)).collect(Collectors.toList());
                // 如果有本周的记录
                if (CollectionUtils.isNotEmpty(customerEstimateRecords)) {
                    CustomerEstimateRecordVO vo = new CustomerEstimateRecordVO();
                    CustomerEstimateRecord record = customerEstimateRecords.get(0);
                    BeanUtils.copyProperties(record, vo);
                    // todo 增加逻辑 以万元进行显示
                    vo.setQuota(vo.getQuota().divide(ten_thousand, 6, RoundingMode.HALF_UP));
                    vo.setEnd_date(week.getEnd_date());
                    vo.setBegin_date(week.getBegin_date());
                    // 设置符合条件的合同
                    if (contract_map.containsKey(item.getId())) {
                        List<ContractApply> contractApplies = contract_map.get(item.getId());
                        BigDecimal pay_cash_amount_count = new BigDecimal(0);
                        BigDecimal displace_amount_count = new BigDecimal(0);
                        if (vo.getBegin_date() != null && vo.getEnd_date() != null) {
                            List<ContractApply> collect = contractApplies.stream().filter(contract -> (contract.getSign_date().isBefore(vo.getEnd_date()) || contract.getSign_date().equals(vo.getEnd_date())) && (contract.getSign_date().isAfter(vo.getBegin_date()) || contract.getSign_date().equals(vo.getBegin_date()))).collect(Collectors.toList());
                            for (ContractApply contractApply : collect) {
                                pay_cash_amount_count = pay_cash_amount_count.add(contractApply.getPay_cash_amount());
                                displace_amount_count = displace_amount_count.add(contractApply.getDisplace_amount());
                            }
                        }
                        vo.setNewest_contract_pay_cash_amount(pay_cash_amount_count);
                        vo.setNewest_contract_displace_amount(displace_amount_count);
                    } else {
                        vo.setNewest_contract_displace_amount(new BigDecimal(0));
                        vo.setNewest_contract_pay_cash_amount(new BigDecimal(0));
                    }
                    list.add(vo);
                } else {
                    // 查看本周是否有合同 有则添加
                    if (contract_map.containsKey(item.getId())) {
                        List<ContractApply> contractApplies = contract_map.get(item.getId());
                        List<ContractApply> collect = contractApplies.stream().filter(contract -> (contract.getSign_date().isBefore(week.getEnd_date()) || contract.getSign_date().equals(week.getEnd_date())) && (contract.getSign_date().isAfter(week.getBegin_date()) || contract.getSign_date().equals(week.getBegin_date()))).collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(collect)) {
                            CustomerEstimateRecordVO vo = new CustomerEstimateRecordVO();
                            BigDecimal pay_cash_amount_count = new BigDecimal(0);
                            BigDecimal displace_amount_count = new BigDecimal(0);
                            for (ContractApply contractApply : collect) {
                                pay_cash_amount_count = pay_cash_amount_count.add(contractApply.getPay_cash_amount());
                                displace_amount_count = displace_amount_count.add(contractApply.getDisplace_amount());
                            }
                            vo.setBegin_date(week.getBegin_date());
                            vo.setEnd_date(week.getEnd_date());
                            vo.setNewest_contract_pay_cash_amount(pay_cash_amount_count);
                            vo.setNewest_contract_displace_amount(displace_amount_count);
                            list.add(vo);
                        }
                    }
                }
            });
            // 增加week_name属性

            list.forEach(record -> {
                record.setWeek_name(dateTimeFormatter.format(record.getBegin_date()) + "~" + dateTimeFormatter.format(record.getEnd_date()));
            });
            item.setEstimateRecordVOList(list.stream().sorted(Comparator.comparing(CustomerEstimateRecordVO::getBegin_date)).collect(Collectors.toList()));
            // 处理拜访记录
            if (follow_map.containsKey(item.getId())) {
                CustomerFollowVO followVO = new CustomerFollowVO();
                CustomerFollow customerFollow = follow_map.get(item.getId()).get(0);
                BeanUtils.copyProperties(customerFollow, followVO);
                if (advance_map.containsKey(customerFollow.getId())) {
                    List<CustomerFollowAdvance> customerFollowAdvances = advance_map.get(customerFollow.getId());
                    List<String> stringList = new ArrayList<>();
                    for (CustomerFollowAdvance customerFollowAdvance : customerFollowAdvances) {
                        if (action_dict_map.containsKey(customerFollowAdvance.getAdvance_id())) {
                            List<Dictionary> dict = action_dict_map.get(customerFollowAdvance.getAdvance_id());
                            stringList.add(dict.get(0).getName());
                        }
                    }
                    followVO.setPropelling_action_name(stringList);
                }
                if (resource_map.containsKey(customerFollow.getId())) {
                    List<CustomerRecommendedResources> customerRecommendedResources = resource_map.get(customerFollow.getId());
                    List<String> stringList = new ArrayList<>();
                    for (CustomerRecommendedResources resource : customerRecommendedResources) {
                        if (resource_dict_map.containsKey(resource.getResources_id())) {
                            List<Dictionary> dict = resource_dict_map.get(resource.getResources_id());
                            stringList.add(dict.get(0).getName());
                        }
                    }
                    followVO.setRecommend_resource_name(stringList);
                }
                item.setCustomerFollowVO(followVO);
            }
            if (item.getVisit_count() == null) {
                item.setVisit_count(0);
            }
            // todo 增加最新的批注
            item.setLastCustomerVisitComments(customerVisitCommentsMap.get(item.getId()));
        });
        // 排序
        companyAdvanceList = companyAdvanceList.stream().sorted(Comparator.comparing(CompanyCustomerAdvanceVO::getCustomerFollowVO, Comparator.nullsFirst(CustomerFollowVO::compareTo)).reversed()).collect(Collectors.toList());
        return companyAdvanceList;
    }


    @Override
    public List<String> getContactById(Long id) {
        return customerContactService.list(Wrappers.<CustomerContact>lambdaQuery().eq(CustomerContact::getCustomer_id, id)).stream().map(CustomerContact::getName).collect(Collectors.toList());
    }

    @Override
    public List<CustomerInfoScheduledJobVO> selectList() {
        return baseMapper.queryList();
    }

    @Override
    public Page<CustomerVisitComments> visitCommentsPage(Integer current_page, Integer page_size, Long customer_id, String comments) {
        Page<CustomerVisitComments> page = new Page<>(current_page, page_size);
        return customerVisitCommentsMapper.selectPage(page, Wrappers.<CustomerVisitComments>lambdaQuery().eq(CustomerVisitComments::getCustomer_id, customer_id).like(StringUtils.isNotEmpty(comments), CustomerVisitComments::getComments, comments).orderByDesc(CustomerVisitComments::getCreated_time));
    }

    @Override
    public Boolean queryCustomerFlow(Long customer_id) {
        if (customer_id == null) {
            return true;
        } else {
            return customerInfoFlowService.count(Wrappers.<CustomerInfoFlow>lambdaQuery().eq(CustomerInfoFlow::getCustomer_id, customer_id).eq(CustomerInfoFlow::getFlow_status, 3).isNull(CustomerInfoFlow::getDeleted_at)) + customerEditFlowService.count(Wrappers.<CustomerEditFlow>lambdaQuery().eq(CustomerEditFlow::getCustomer_id, customer_id).eq(CustomerEditFlow::getFlow_status, 3).isNull(CustomerEditFlow::getDeleted_at)) == 0;
        }
    }

    @Override
    public MiniCustomerInfoVO getDeteil(Long id) {
        MiniCustomerInfoVO vo = baseMapper.queryDetail(id);
        vo.setFunnels(customerFunnelService.list(Wrappers.<CustomerFunnel>lambdaQuery().eq(CustomerFunnel::getCustomer_id, vo.getId())).stream().map(CustomerFunnel::getFunnel_type_id).collect(Collectors.toList()));
        vo.setSelection_reasons(customerSelectionReasonService.list(Wrappers.<CustomerSelectionReason>lambdaQuery().eq(CustomerSelectionReason::getCustomer_id, vo.getId())).stream().map(CustomerSelectionReason::getSelection_reason_id).collect(Collectors.toList()));
        // 查询字典数据
        Map<Long, Dictionary> map1 = dictionaryService.listByCode("khxg-xsld").stream().collect(Collectors.toMap(Dictionary::getId, Function.identity()));
        Map<Long, Dictionary> map2 = dictionaryService.listByCode("khxg-xzyy").stream().collect(Collectors.toMap(Dictionary::getId, Function.identity()));
        List<String> funnels_list = new ArrayList<>();
        List<String> aelection_reasons_list = new ArrayList<>();
        vo.getFunnels().forEach(item -> {
            funnels_list.add(map1.get(item).getName());
        });
        vo.getSelection_reasons().forEach(item -> {
            aelection_reasons_list.add(map2.get(item).getName());
        });
        vo.setFunnels_name(StringUtils.join(funnels_list.toArray(), "、"));
        vo.setSelection_reasons_name(StringUtils.join(aelection_reasons_list.toArray(), "、"));
        vo.setIs_company_customer(BossUserEnum.getEnumById(vo.getPerson_in_charge_id()) != null);
        return vo;
    }

    @Override
    public List<CompanyCustomerAdvanceVO> queryCustomerInfoPage(Page<CompanyCustomerAdvanceVO> page, Integer type, List<Long> boss_ids, String name, Long user_id) {
        return baseMapper.queryCustomerInfoPage(page, type, boss_ids, name, user_id);
    }

    @Override
    public List<CompanyCustomerAdvanceVO> queryCustomerInfoPageOrderByFollowDesc(Page<CompanyCustomerAdvanceVO> page, Integer type, List<Long> boss_ids, String name, Long user_id) {
        return baseMapper.queryCustomerInfoPageOrderByFollowDesc(page, type, boss_ids, name, user_id);
    }

    @Override
    public List<CustomerInfo> companyListAll(Integer type) {
        List<Long> boss_ids = new ArrayList<>(Arrays.asList(BossUserEnum.values())).stream().map(BossUserEnum::getId).collect(Collectors.toList());
        Long user_id = ThreadLocalUserUtil.get().getId();
        return baseMapper.queryAllByType(type, user_id, boss_ids);
    }
}
